﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Net.Http;
using System.Text;

namespace XUtility
{
    /// <summary>
    /// JSON 格式 响应结果 使用 Easyui 来提示信息
    /// </summary>
    public class JsonClass
    {
        #region 序列化 反序列化
        /// <summary>
        /// 将指定的对象序列化成 JSON 数据。
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <param name="dtFormat">日期格式形式</param>
        /// <param name="enableNULL">是否把null字段也转换成json</param>
        /// <returns></returns>
        public static String ToJson(Object obj, String dtFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss", Boolean enableNULL = false)
        {
            String json = "{}";
            try
            {
                if (null == obj)
                {
                    Type type = obj.GetType();
                    if (type.IsArray || type.IsGenericType)
                        json = "[]";
                }
                else
                {
                    JsonSerializerSettings jss = new JsonSerializerSettings();
                    jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 忽略引用属性，一般用来codefirst导航属性
                    if (!enableNULL)
                    {
                        jss.NullValueHandling = NullValueHandling.Ignore; // 忽略null值的属性
                    }
                    else
                    {
                        jss.NullValueHandling = NullValueHandling.Include;
                    }
                    #region 时间格式化
                    IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
                    //这里使用自定义日期格式，如果不使用的话，默认是ISO8601格式     
                    timeConverter.DateTimeFormat = dtFormat;
                    jss.Converters.Add(timeConverter);
                    #endregion

                    //if (nullFormat != null)
                    //{
                    //    DataNullCreationConverter nullConverter = new DataNullCreationConverter();
                    //    nullConverter.NullFormat = nullFormat;
                    //    jss.Converters.Add(nullConverter);
                    //} 

                    // Newtonsoft.Json.Formatting.Indented 以缩进的形式显示结果
                    json = JsonConvert.SerializeObject(obj, jss);
                }
            }
            catch { }
            return json;
        }

        /// <summary>
        /// 用内置支持的时间格式化来转json
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <param name="dtFormat">日期格式类型</param>
        /// <param name="enableNULL">是否把null字段也转换成json</param>
        /// <returns></returns>
        public static String ToJson(Object obj, DateFormatHandling dtFormat, Boolean enableNULL = false)
        {
            String json = "{}";
            try
            {
                if (null == obj)
                {
                    Type type = obj.GetType();
                    if (type.IsArray || type.IsGenericType)
                        json = "[]";
                }
                else
                {
                    JsonSerializerSettings jss = new JsonSerializerSettings();
                    jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 忽略引用属性，一般用来codefirst导航属性
                    if (!enableNULL)
                    {
                        jss.NullValueHandling = NullValueHandling.Ignore; // 忽略null值的属性
                    }
                    else
                    {
                        jss.NullValueHandling = NullValueHandling.Include;
                    }
                    #region 时间格式化
                    jss.DateFormatHandling = dtFormat;
                    #endregion

                    //if (nullFormat != null)
                    //{
                    //    DataNullCreationConverter nullConverter = new DataNullCreationConverter();
                    //    nullConverter.NullFormat = nullFormat;
                    //    jss.Converters.Add(nullConverter);
                    //} 

                    // Newtonsoft.Json.Formatting.Indented 以缩进的形式显示结果
                    json = JsonConvert.SerializeObject(obj, jss);
                }
            }
            catch { }
            return json;
        }

        /// <summary>
        /// 将指定的 JSON 数据反序列化成指定对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="json">JSON 数据。</param>
        /// <returns></returns>
        public static T FromJson<T>(String json)
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(json);
            }
            catch
            {
                return default(T);
            }
        }
        /// <summary>
        /// 将指定的 JSON 数据反序列化成指定对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="json">JSON 数据。</param>
        /// <returns></returns>
        public static T FromJson<T>(T t, String json)
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(json);
            }
            catch
            {
                return default(T);
            }
        }
        /// <summary>
        /// 将指定的 JSON 数据反序列化成指定对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="json">JSON 数据。</param>
        /// <returns></returns>
        public static dynamic FromJson(Type type, String json)
        {
            try
            {
                return JsonConvert.DeserializeObject(json, type);
            }
            catch
            {
                return System.Activator.CreateInstance(type);
            }
        }
        /// <summary>
        /// 将指定的 JSON 数据反序列化成指定对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="json">JSON 数据。</param>
        /// <returns></returns>
        public static IList<T> FromJsonList<T>(T t, String json)
        {
            try
            {
                return JsonConvert.DeserializeObject<IList<T>>(json);
            }
            catch
            {
                return new List<T>();
            }
        }
        #endregion

        #region 新新重写
        public static String XResponseResult(Boolean success, String msg = "", Object attr = null)
        {
            XJsonInfo info = new XJsonInfo();
            info.success = success;
            info.msg = msg;
            info.attr = attr;
            return XResponseResult(info);
        }

        public static String XResponseResult(XJsonInfo info)
        {
            String diy_msg = info.msg;
            String diy_icon = info.icon;

            if (info.success)
            {
                info.msg = "操作成功！";
                info.icon = "info";
            }
            else
            {
                info.msg = "操作失败！";
                info.icon = "error";
            }

            if (!String.IsNullOrWhiteSpace(diy_msg))
            {
                info.msg = diy_msg;
            }

            if (!String.IsNullOrWhiteSpace(diy_icon))
            {
                info.icon = diy_icon;
            }

            return JsonClass.ToJson(info);
        }

        #endregion
    }

    public partial class XJsonInfo
    {
        public XJsonInfo()
            : this(true)
        {

        }

        public XJsonInfo(Int32 re)
        {
            id = re.ToString();
            if (re > 0)
            {
                success = true;

            }
            else
            {
                success = false;

            }
            Create();
        }

        public XJsonInfo(DbContext db)
        {
            try
            {
                db.SaveChanges();
                success = true;
                Create();

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public XJsonInfo(Boolean c_success, String c_msg = null, Object c_attr = null, Int32 c_total = 0, String c_formatter = "application/json")
        {
            id = "";
            success = c_success;
            msg = c_msg;
            attr = c_attr;
            total = c_total;
            formatter = c_formatter;
            Create();
        }
        public String id { get; set; }
        public Int32 total { get; set; } = 0;
        public Boolean success { get; set; }
        public String msg { get; set; }
        public String icon { get; set; }
        public Object attr { get; set; }
        public String code { get; set; }
        //public Int32 StatusCode { get; set; }
        //public StringContent Content { get; set; }
        /// <summary>
        /// 可选
        /// <para>application/x-www-form-urlencoded</para>
        /// </summary>
        public String formatter { get; set; }

        private void Create()
        {
            formatter = formatter ?? "application/x-www-form-urlencoded";

            if (success)
            {
                if (msg == null)
                {
                    msg = "操作成功！";
                }
                icon = "info";
                //StatusCode = 200;

            }
            else
            {
                if (msg == null)
                {
                    msg = "操作失败！";
                }
                icon = "error";
                //StatusCode = 500;
            }
            //Content = new StringContent(JsonClass.ToJson(this.attr), Encoding.GetEncoding("UTF-8"), formatter);
        }

        /// <summary>
        /// 转换为JsonClass.XResponseResult格式的json字符串
        /// </summary>
        /// <returns></returns>
        public String ToRequestJson()
        {
            if (this == null)
            {
                return JsonClass.XResponseResult(false);
            }
            else
            {
                return JsonClass.XResponseResult(this);
            }
        }

        /// <summary>
        /// attr转换为集合
        /// </summary>
        public IList<T> ToAttrList<T>()
        {
            if (this == null)
            {
                return null;
            }
            else
            {
                var json = JsonClass.ToJson(this.attr);
                return JsonClass.FromJson<IList<T>>(json);
            }
        }

        /// <summary>
        /// attr转换为实体
        /// </summary>
        public T ToAttrModel<T>()
        {
            if (this == null)
            {
                return default(T);
            }
            else
            {
                var json = JsonClass.ToJson(this.attr);
                return JsonClass.FromJson<T>(json);
            }
        }

        /// <summary>
        /// attr转换为实体
        /// </summary>
        public Stream ToAttrStream()
        {
            if (this == null)
            {
                return null;
            }
            else
            {
                return (Stream)(this.attr);
            }
        }

        public XJsonInfo SetData(Object p_attr, Int32 p_total = 1)
        {
            this.attr = p_attr;
            this.total = p_attr == null ? 0 : p_total;
            return this;
        }

        public XJsonInfo SetMsg(String p_msg)
        {
            this.msg = p_msg;
            return this;
        }

        public XJsonInfo SetCode(String p_code)
        {
            this.code = p_code;
            return this;
        }

        /// <summary>
        /// 转为微信用的HttpResponseMessage信息
        /// </summary>
        /// <returns></returns>
        public HttpResponseMessage ToWeiXinResponseMsg()
        {
            return this.ToRequestJson().ToHttpResponseMsg();
        }
    }




    //public class DataNullCreationConverter : JsonConverter
    //{
    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    public String NullFormat { get; set; }

    //    /// <summary>
    //    /// 是否允许转换
    //    /// </summary>
    //    public override bool CanConvert(Type objectType)
    //    {
    //        //bool canConvert = false;
    //        //switch (objectType.FullName)
    //        //{
    //        //    case "System.DBNull":
    //        //        canConvert = true;
    //        //        break;
    //        //}
    //        return true;
    //    }
    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    /// <param name="reader"></param>
    //    /// <param name="objectType"></param>
    //    /// <param name="existingValue"></param>
    //    /// <param name="serializer"></param>
    //    /// <returns></returns>
    //    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    //    {
    //        return existingValue;
    //    }
    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    /// <param name="writer"></param>
    //    /// <param name="value"></param>
    //    /// <param name="serializer"></param>
    //    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    //    {
    //        if (value == null)
    //            if (NullFormat != null)
    //                writer.WriteValue(NullFormat);
    //    }
    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    public override bool CanRead
    //    {
    //        get
    //        {
    //            return false;
    //        }
    //    }
    //    /// <summary>
    //    /// 是否允许转换JSON字符串时调用
    //    /// </summary>
    //    public override bool CanWrite
    //    {
    //        get
    //        {
    //            return true;
    //        }
    //    }
    //}
}
